﻿using System;
using System.Collections.Generic;
 
using System.Text;
using System.Runtime.InteropServices;


namespace HDF5
{

    using hid_t = System.Int32;
    using herr_t = System.Int32;
    using hsize_t = System.UInt64;
    using hunsigned = System.UInt32;
    using htri_t = System.Int32;
    using ssize_t = System.Int64;
    using size_t = System.UInt64;
    using haddr_t = System.Int32;
    using hssize_t = System.Int64;
    
    /* Different types of dataspaces */
    public enum H5S_class_t {
        H5S_NO_CLASS         = -1,  /*error                                      */
        H5S_SCALAR           = 0,   /*scalar variable                            */
        H5S_SIMPLE           = 1,   /*simple data space                          */
        H5S_NULL             = 2    /*null data space                            */
    }  

    /* Different ways of combining selections */
    public enum H5S_seloper_t {
        H5S_SELECT_NOOP      = -1,  /* error                                     */
        H5S_SELECT_SET       = 0,   /* Select "set" operation 		     */
        H5S_SELECT_OR,              /* Binary "or" operation for hyperslabs
                                     * (add new selection to existing selection)
                                     * Original region:  AAAAAAAAAA
                                     * New region:             BBBBBBBBBB
                                     * A or B:           CCCCCCCCCCCCCCCC
                                     */
        H5S_SELECT_AND,             /* Binary "and" operation for hyperslabs
                                     * (only leave overlapped regions in selection)
                                     * Original region:  AAAAAAAAAA
                                     * New region:             BBBBBBBBBB
                                     * A and B:                CCCC
                                     */
        H5S_SELECT_XOR,             /* Binary "xor" operation for hyperslabs
                                     * (only leave non-overlapped regions in selection)
                                     * Original region:  AAAAAAAAAA
                                     * New region:             BBBBBBBBBB
                                     * A xor B:          CCCCCC    CCCCCC
                                     */
        H5S_SELECT_NOTB,            /* Binary "not" operation for hyperslabs
                                     * (only leave non-overlapped regions in original selection)
                                     * Original region:  AAAAAAAAAA
                                     * New region:             BBBBBBBBBB
                                     * A not B:          CCCCCC
                                     */
        H5S_SELECT_NOTA,            /* Binary "not" operation for hyperslabs
                                     * (only leave non-overlapped regions in new selection)
                                     * Original region:  AAAAAAAAAA
                                     * New region:             BBBBBBBBBB
                                     * B not A:                    CCCCCC
                                     */
        H5S_SELECT_APPEND,          /* Append elements to end of point selection */
        H5S_SELECT_PREPEND,         /* Prepend elements to beginning of point selection */
        H5S_SELECT_INVALID          /* Invalid upper bound on selection operations */
    }  

    /* Enumerated type for the type of selection */
    public enum H5S_sel_type{
        H5S_SEL_ERROR	= -1, 	/* Error			*/
        H5S_SEL_NONE	= 0,    /* Nothing selected 		*/
        H5S_SEL_POINTS	= 1,    /* Sequence of points selected	*/
        H5S_SEL_HYPERSLABS  = 2,    /* "New-style" hyperslab selection defined	*/
        H5S_SEL_ALL		= 3,    /* Entire extent selected	*/
        H5S_SEL_N			/*THIS MUST BE LAST		*/
    } 

    public static class H5S
    {

        public static hsize_t H5S_ALL = 0;
        public static hsize_t H5S_UNLIMITED = unchecked((hsize_t)(-1));
        public static hsize_t H5S_MAX_RANK = 32;

        // imports

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern hid_t H5Screate( H5S_class_t type )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern hid_t H5Scopy( hid_t space_id )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Sclose( hid_t space_id )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern hid_t H5Sdecode (IntPtr buf)  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Sencode(hid_t obj_id, IntPtr buf, out size_t nalloc)  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern hid_t H5Screate_simple( int rank, hsize_t[]  dims,  hsize_t[] maxdims )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern htri_t H5Sis_simple( hid_t space_id )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Soffset_simple(hid_t space_id,   hssize_t[] offset )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern int H5Sget_simple_extent_dims(hid_t space_id,[Out] hsize_t[] dims,[Out] hsize_t[] maxdims )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern  int H5Sget_simple_extent_ndims( hid_t space_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern  hssize_t H5Sget_simple_extent_npoints( hid_t space_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern H5S_class_t H5Sget_simple_extent_type( hid_t space_id )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Sextent_copy(hid_t dest_space_id, hid_t source_space_id )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern htri_t H5Sextent_equal( hid_t space1_id, hid_t space2_id )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Sset_extent_simple( hid_t space_id, int rank, [In] hsize_t[] current_size, [In] hsize_t[] maximum_size )   ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Sset_extent_none( hid_t space_id )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern H5S_sel_type H5Sget_select_type(hid_t space_id)  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern hssize_t H5Sget_select_npoints( hid_t space_id )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern hssize_t H5Sget_select_hyper_nblocks(hid_t space_id )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Sget_select_hyper_blocklist(hid_t space_id, hsize_t startblock, hsize_t numblocks, [Out]hsize_t[] buf )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern hssize_t H5Sget_select_elem_npoints(hid_t space_id )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Sget_select_elem_pointlist(hid_t space_id, hsize_t startpoint, hsize_t numpoints, [Out] hsize_t[] buf);

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Sget_select_bounds(hid_t space_id, out hsize_t start,out hsize_t end ) ;

        //[DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        //public static extern herr_t H5Sselect_elements( hid_t space_id, H5S_seloper_t op, size_t num_elements, const hsize_t *coord ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Sselect_all( hid_t dspace_id )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Sselect_none(hid_t space_id) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern htri_t H5Sselect_valid( hid_t space_id ) ;

        //[DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        //public static extern herr_t H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t *start, const hsize_t *stride, const hsize_t *count, const hsize_t *block ) ;
    }
}
